Qt Theme 纯 qss 的 Qt 主题

简介

源码地址:https://github.com/hubenchang0515/QtTheme/

预览

Qt Theme 是一个纯 qss 的 Qt 主题项目,能够极为简单对已有项目的风格进行改进。

支持 C++、PyQt5、PyQt6、PySide2、PySide6,并以 WebAssembly 的方式在 GitHub Pages 上发布。

示例

安装

这里演示一下在 Python 上的使用,首先进行安装:

1pip install QtTheme

原生样式及代码

让 Deep Seek 随便帮我写个界面作为示例:

deepseek

1import sys
2from PyQt5.QtWidgets import *
3from PyQt5.QtGui import QPixmap, QFont
4from PyQt5.QtCore import Qt, QTimer
5
6class DemoWindow(QMainWindow):
7    def __init__(self):
8        super().__init__()
9        self.setWindowTitle("PyQt Widget 演示界面")
10        self.setGeometry(100, 100, 800, 600)
11        
12        # 创建中心widget和主布局
13        central_widget = QWidget()
14        self.setCentralWidget(central_widget)
15        main_layout = QVBoxLayout(central_widget)
16
17        # 添加功能区域
18        self.create_input_section(main_layout)
19        self.create_selection_section(main_layout)
20        self.create_display_section(main_layout)
21        self.create_progress_section(main_layout)
22        
23        # 添加状态栏
24        self.statusBar().showMessage("就绪")
25
26        # 初始化进度条
27        self.progress_value = 0
28        self.update_progress()
29
30    def create_input_section(self, layout):
31        group = QGroupBox("输入控件")
32        grid = QGridLayout()
33
34        # 文本输入
35        self.line_edit = QLineEdit()
36        self.line_edit.setPlaceholderText("单行文本输入...")
37        grid.addWidget(QLabel("单行文本:"), 0, 0)
38        grid.addWidget(self.line_edit, 0, 1)
39
40        # 多行文本
41        self.text_edit = QTextEdit()
42        self.text_edit.setPlaceholderText("多行文本输入...")
43        grid.addWidget(QLabel("多行文本:"), 1, 0)
44        grid.addWidget(self.text_edit, 1, 1)
45
46        # 数字输入
47        self.spin_box = QSpinBox()
48        self.spin_box.setRange(0, 100)
49        grid.addWidget(QLabel("数字输入:"), 2, 0)
50        grid.addWidget(self.spin_box, 2, 1)
51
52        group.setLayout(grid)
53        layout.addWidget(group)
54
55    def create_selection_section(self, layout):
56        group = QGroupBox("选择控件")
57        hbox = QHBoxLayout()
58
59        # 复选框
60        vbox = QVBoxLayout()
61        self.check1 = QCheckBox("选项1")
62        self.check2 = QCheckBox("选项2")
63        vbox.addWidget(self.check1)
64        vbox.addWidget(self.check2)
65        hbox.addLayout(vbox)
66
67        # 单选框
68        vbox = QVBoxLayout()
69        self.radio1 = QRadioButton("单选1")
70        self.radio2 = QRadioButton("单选2")
71        self.radio1.setChecked(True)
72        vbox.addWidget(self.radio1)
73        vbox.addWidget(self.radio2)
74        hbox.addLayout(vbox)
75
76        # 下拉列表
77        self.combo = QComboBox()
78        self.combo.addItems(["选项A", "选项B", "选项C"])
79        hbox.addWidget(self.combo)
80
81        group.setLayout(hbox)
82        layout.addWidget(group)
83
84    def create_display_section(self, layout):
85        group = QGroupBox("显示控件")
86        hbox = QHBoxLayout()
87
88        # 标签
89        self.label = QLabel("这是一个标签")
90        self.label.setAlignment(Qt.AlignCenter)
91        self.label.setStyleSheet("border: 1px solid gray; padding: 10px;")
92        hbox.addWidget(self.label)
93
94        # 图片显示
95        pixmap = QPixmap(100, 50)
96        pixmap.fill(Qt.blue)
97        image_label = QLabel()
98        image_label.setPixmap(pixmap)
99        hbox.addWidget(image_label)
100
101        # 列表控件
102        self.list_widget = QListWidget()
103        self.list_widget.addItems(["项目1", "项目2", "项目3"])
104        hbox.addWidget(self.list_widget)
105
106        group.setLayout(hbox)
107        layout.addWidget(group)
108
109    def create_progress_section(self, layout):
110        group = QGroupBox("进度控件")
111        vbox = QVBoxLayout()
112
113        # 进度条
114        self.progress_bar = QProgressBar()
115        self.progress_bar.setValue(0)
116        vbox.addWidget(self.progress_bar)
117
118        # 滑块
119        self.slider = QSlider(Qt.Horizontal)
120        self.slider.setRange(0, 100)
121        self.slider.valueChanged.connect(self.on_slider_changed)
122        vbox.addWidget(self.slider)
123
124        # 控制按钮
125        btn_layout = QHBoxLayout()
126        self.start_btn = QPushButton("开始进度")
127        self.start_btn.clicked.connect(self.start_progress)
128        self.reset_btn = QPushButton("重置")
129        self.reset_btn.clicked.connect(self.reset_progress)
130        btn_layout.addWidget(self.start_btn)
131        btn_layout.addWidget(self.reset_btn)
132
133        vbox.addLayout(btn_layout)
134        group.setLayout(vbox)
135        layout.addWidget(group)
136
137    def on_slider_changed(self, value):
138        self.progress_bar.setValue(value)
139        self.statusBar().showMessage(f"滑块值: {value}")
140
141    def start_progress(self):
142        self.timer = QTimer()
143        self.timer.timeout.connect(self.update_progress)
144        self.timer.start(100)
145
146    def update_progress(self):
147        self.progress_value += 1
148        if self.progress_value > 100:
149            self.timer.stop()
150            return
151        self.progress_bar.setValue(self.progress_value)
152        self.slider.setValue(self.progress_value)
153
154    def reset_progress(self):
155        self.progress_value = 0
156        self.progress_bar.setValue(0)
157        self.slider.setValue(0)
158
159if __name__ == "__main__":
160    app = QApplication(sys.argv)
161    window = DemoWindow()
162    window.show()
163    sys.exit(app.exec_())

运行起来看看:

native ui

设置全局样式

导入 QtTheme,并通过 Qt 资源系统读取并设置样式即可:

1from PyQt5.QtCore import QFile
2import QtTheme.PyQt5
3
4class DemoWindow(QMainWindow):
5    def __init__(self):
6        # 省略...
7
8        qss = QFile(":/QtTheme/theme/Flat/Dark/Blue/Pink.qss")
9        qss.open(QFile.OpenModeFlag.ReadOnly)
10        self.setStyleSheet(qss.readAll().data().decode())

dark ui

设置颜色

最后根据需要,通过 QWidget.setProperty 对 widgets 设置颜色:

1    def create_progress_section(self, layout):
2        # 省略 ...
3        self.start_btn.setProperty("Color", "Primary")
4        self.reset_btn.setProperty("Color", "Danger")

color ui

导出资源

你也可以不安装 QtTheme,而是通过 在线页面 导出资源文件, 通过 RCC 将其加入你的项目:

1pyrcc5 -o resource.py QtTheme.qrc

只需要修改导入方式,其余代码一致:

1from PyQt5.QtCore import QFile
2import resource   # 改为导入生成的 resource.py
3
4class DemoWindow(QMainWindow):
5    def __init__(self):
6        # 省略...
7
8        qss = QFile(":/QtTheme/theme/Flat/Dark/Blue/Pink.qss")
9        qss.open(QFile.OpenModeFlag.ReadOnly)
10        self.setStyleSheet(qss.readAll().data().decode())
11